package com.lkc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lkc.domain.ResponseResult;
import com.lkc.domain.dto.AddQuestionDto;
import com.lkc.domain.dto.AnswerDto;
import com.lkc.domain.entity.Question;
import com.lkc.domain.entity.QuestionExam;
import com.lkc.domain.vo.QuestionVo;
import com.lkc.domain.vo.UpdateVo;
import com.lkc.enums.AppHttpCodeEnum;
import com.lkc.enums.SystemContains;
import com.lkc.exception.SystemException;
import com.lkc.mapper.ExamMapper;
import com.lkc.mapper.QuestionExamMapper;
import com.lkc.mapper.QuestionMapper;
import com.lkc.service.QuestionService;
import com.lkc.utils.security.LoginUser;
import org.mockito.internal.util.StringUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * (Question)表服务实现类
 *
 * @author 椰咩咩咩
 * @since 2022-12-27 14:41:32
 */
@Service("questionService")
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService {

    @Resource
    private QuestionMapper questionMapper;
    @Resource
    private QuestionExamMapper questionExamMapper;
    @Resource
    private ExamMapper examMapper;

    @Override
    public ResponseResult getQuestions(Long eId) {
        List<Question> questions = getQuestionsByEid(eId);
        questions = questions.stream().map(question -> question.setAnswer(null)).collect(Collectors.toList());
        return ResponseResult.okResult(getQuestionVo(questions, eId, false));
    }

    @Override
    public ResponseResult getExamedQuestions(Long eId) {
        List<Question> questions = getQuestionsByEid(eId);
        return ResponseResult.okResult(getQuestionVo(questions, eId, true));
    }

    @Override
    public ResponseResult delFromExam(Long qId, Long eId) {
        if (!LoginUser.isTeacher()) {
            throw new SystemException(AppHttpCodeEnum.NO_OPERATOR_AUTH);
        }
        UpdateWrapper<QuestionExam> wrapper = new UpdateWrapper<>();
        wrapper.eq("question_id", qId);
        wrapper.eq("exam_id", eId);
        int row = questionExamMapper.delete(wrapper);
        return row > 0 ? ResponseResult.okResult(new UpdateVo(AppHttpCodeEnum.DELETE_SUCCESS)) : ResponseResult.errorResult(AppHttpCodeEnum.DELETE_ERROR);
    }

    @Override
    public ResponseResult addQuestionToExam(Question question) {
        if (!LoginUser.isTeacher()) {
            throw new SystemException(AppHttpCodeEnum.NO_OPERATOR_AUTH);
        }
        questionMapper.insert(question);
        QuestionExam questionExam = new QuestionExam(question.getId(), question.getExamId(), question.getScore());
        questionExamMapper.insert(questionExam);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult updateQuestion(Question question) {
        updateById(question);
        questionExamMapper.updateById(new QuestionExam(question.getId(), question.getExamId(), question.getScore()));
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult checkAnswer(AnswerDto answerDto) {
        Integer singleScore = getScore(answerDto.getSingle(), getQuestionsByEid(answerDto.getExamId()));
        Integer judgeScore = getScore(answerDto.getSingle(), getQuestionsByEid(answerDto.getExamId()));
        return ResponseResult.okResult(singleScore + judgeScore);
    }

    private Integer getScore(List<Question> answers, List<Question> questions) {
        Integer score = 0;
        for (Question q : questions) {
            //TODO:判断填空题的分数
            if (q.getType().equals(SystemContains.QUESTION_COMPLETION)) {

            } else {
                Integer s = 0;
                if (StringUtils.hasText(q.getAnswer())) {
                    s = isCorrect(q, questions);
                }
                score += s;
            }
        }
        return score;
    }

    private Integer isCorrect(Question q, List<Question> questions) {
        List<Question> correct = questions.stream()
                .filter(question -> question.getId().equals(q.getId()))
                .collect(Collectors.toList());
        Question correctQues = correct.get(0);
        // TODO: 3为固定分数，应从数据库里面获取分数
        return correctQues.getAnswer().equals(q.getAnswer()) ? 3 : 0;
    }

    private List<Question> getQuestionsByEid(Long eId) {
        //根据eid查询出对应的qid
        LambdaQueryWrapper<QuestionExam> questionExamWrapper = new LambdaQueryWrapper<>();
        questionExamWrapper.eq(QuestionExam::getExamId, eId);
        List<QuestionExam> questionExams = questionExamMapper.selectList(questionExamWrapper);
        List<Long> qIds = questionExams.stream().map(QuestionExam::getQuestionId).collect(Collectors.toList());
        //查询exam下的所有question
        LambdaQueryWrapper<Question> questionWrapper = new LambdaQueryWrapper<>();
        questionWrapper.in(Question::getId, qIds);
        questionWrapper.orderByAsc(Question::getId);
        List<Question> questions = list(questionWrapper);
        questions = questions.stream()
                .map(question -> question.setScore(getEachScore(questionExams, question.getId())))
                .collect(Collectors.toList());
        return questions;
    }

    private Integer getEachScore(List<QuestionExam> questionExams, Long qId) {
        questionExams = questionExams.stream().filter(qe -> qe.getQuestionId().equals(qId)).collect(Collectors.toList());
        if (questionExams.size() <= 0) {
            return 0;
        }
        return questionExams.get(0).getScore();
    }

    private QuestionVo getQuestionVo(List<Question> questions, Long eId, boolean isExamed) {
        QuestionVo questionVo = new QuestionVo();
        //单选题
        List<Question> single = questions.stream()
                .filter(question -> question.getType().equals(SystemContains.QUESTION_SINGLE))
                .collect(Collectors.toList());
        Integer singleScore = questionExamMapper.getTotal(SystemContains.QUESTION_SINGLE, eId);
        questionVo.setSingle(single);
        questionVo.setSingleScore(singleScore);

        List<Question> judge = questions.stream()
                .filter(question -> question.getType().equals(SystemContains.QUESTION_JUDGE))
                .collect(Collectors.toList());
        questionVo.setJudge(judge);
        Integer judgeScore = questionExamMapper.getTotal(SystemContains.QUESTION_JUDGE, eId);
        questionVo.setJudgeScore(judgeScore);

        List<Question> completion = new ArrayList<>();
        if (isExamed) {
            completion = questions.stream()
                    .filter(question -> question.getType().equals(SystemContains.QUESTION_COMPLETION))
                    .collect(Collectors.toList());
        } else {
            //TODO:考试时候没有填空题
//            completion = questions.stream()
//                    .filter(question -> question.getType().equals(SystemContains.QUESTION_COMPLETION))
//                    .map(question -> question.setA(null))
//                    .map(question -> question.setB(null))
//                    .map(question -> question.setC(null))
//                    .map(question -> question.setD(null))
//                    .collect(Collectors.toList());
            completion = null;
        }

        questionVo.setCompletion(completion);
        Integer completionScore = questionExamMapper.getTotal(SystemContains.QUESTION_COMPLETION, eId);
        questionVo.setCompletionScore(completionScore);

        questionVo.setTotalScore(singleScore + judgeScore + completionScore);
        return questionVo;
    }
}

